package com.zeny.edu.eduservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zeny.edu.eduservice.entity.EduSubject;
import com.zeny.edu.eduservice.mapper.EduSubjectMapper;
import com.zeny.edu.eduservice.service.EduSubjectService;
import com.zeny.edu.eduservice.entity.dto.SubjectNestedVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程科目 服务实现类
 * </p>
 *
 * @author zeny
 * @since 2020-02-29
 */
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {

    /**
     * @param file
     * @return void
     * @Description 读取excel文件的内容，添加到分类表
     * @Date 2020/2/29 0029 21:37
     **/
    @Override
    public List<String> importExcelSubject(MultipartFile file) {
        List<String> msg = new ArrayList<>();
        if (file == null) {
            msg.add("文件已丢失，请重新上传");
            return msg;
        }
        //获得扩展名
        String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (StringUtils.isNotBlank(extName) && (!"xls".equals(extName) && !"xlsx".equals(extName))) {
            msg.add("文件格式错误~");
            return msg;
        }
        InputStream in = null;
        try {
            //1、获得文件的输入流
            in = file.getInputStream();
            //2、创建workbook
            Workbook workbook = null;
            if ("xls".equals(extName)) {
                workbook = new HSSFWorkbook(in);
            }
            if ("xlsx".equals(extName)) {
                workbook = new XSSFWorkbook(in);
            }
            //3、从workbook中获取sheet1
            Sheet sheet = workbook.getSheetAt(0);

            //4、sheet中获取row
            //最后一行的索引
            int lastRowNum = sheet.getLastRowNum();
            if (lastRowNum <= 0) {
                msg.add("文件内容为空~");
                return msg;
            }
            for (int i = 1; i <= lastRowNum; i++) {
                Row row = sheet.getRow(i);
                if (row == null) {
                    msg.add("表格的第" + (i + 1) + "行为空~");
                    continue;
                }
                Cell cellOne = row.getCell(0);
                if (cellOne == null) {
                    msg.add("表格的第" + (i + 1) + "行第第一列为空~");
                    continue;
                }
                //一级分类的值
                String cellOneValue = cellOne.getStringCellValue();
                //添加一级分类
                EduSubject existOne = isExistOne(cellOneValue, "0");
                String parentId = "";
                if (existOne == null) {
                    //一级分类的添加
                    EduSubject eduSubject = new EduSubject();
                    eduSubject.setTitle(cellOneValue);
                    eduSubject.setParentId("0");
                    eduSubject.setSort(0);
                    baseMapper.insert(eduSubject);
                    parentId = eduSubject.getId();
                } else {
                    //已存在
                    parentId = existOne.getId();
                }

                Cell cellTwo = row.getCell(1);
                if (cellTwo == null) {
                    msg.add("表格的第" + (i + 1) + "行第二列为空~");
                    continue;
                }
                String cellTwoValue = cellTwo.getStringCellValue();
                EduSubject existTwo = isExistOne(cellTwoValue, parentId);
                if (existTwo == null) {
                    //二级分类的添加
                    EduSubject eduSubject = new EduSubject();
                    eduSubject.setTitle(cellTwoValue);
                    eduSubject.setParentId(parentId);
                    eduSubject.setSort(0);
                    baseMapper.insert(eduSubject);
                }
            }

        } catch (Exception e) {
            throw new RuntimeException("对不起，崩溃了~~~，请重试~~~");
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return msg;
    }

    /**
     * @param
     * @return java.util.List<com.zeny.edu.eduservice.entity.dto.SubjectNestedVo>
     * @Description 嵌套数据列表
     * @Date 2020/3/2 0002 15:22
     **/
    @Override
    public List<SubjectNestedVo> nestedList() {
        //从数据库中查询并封装到subjectNestedVoList
        List<SubjectNestedVo> subjectNestedVoList = getSubjectNestedVoListByDb();
        //利用hashmap构建索引
        Map<String, Object> map = getSubMap(subjectNestedVoList);
        List<SubjectNestedVo> result = new ArrayList<>();
        for (SubjectNestedVo subjectNestedVo : subjectNestedVoList) {
            SubjectNestedVo child = subjectNestedVo;
            if (child.getParentId().equals("0")) {
                result.add(child);
            }else {
                String parentId = child.getParentId();
                SubjectNestedVo parent = (SubjectNestedVo) map.get(parentId);
                parent.getChildren().add(child);
            }
        }
        return result;
    }

    /**
     * @Description 删除子节点
     * @Date 2020/3/2 0002 16:38
     * @param id
     * @return boolean
     **/
    @Override
    public boolean deleteById(String id) {
        EduSubject eduSubject = baseMapper.selectById(id);
        if (eduSubject == null) {
            return false;
        }
        //判断是否存在子节点
        boolean flag = isExistChild(id);
        if (flag) {
            return false;
        }else {
            baseMapper.deleteById(id);
            return true;
        }
    }

    /**
     * @Description 新增一级分类
     * @Date 2020/3/2 0002 17:52
     * @param eduSubject 
     * @return boolean
     **/
    @Override
    public synchronized boolean saveOneLevel(EduSubject eduSubject) {
        //检查是否已经存在
        EduSubject eduSubjectFromDb = getByTitle(eduSubject.getTitle());
        if (eduSubjectFromDb == null) {
            eduSubject.setParentId("0");
            return super.save(eduSubject);
        }
        return false;
    }

    /**
     * @Description 新增二级分类
     * @Date 2020/3/2 0002 19:14
     * @param eduSubject
     * @return boolean
     **/
    @Override
    public synchronized boolean saveTwoLevel(EduSubject eduSubject) {
        //检查是否已经存在
        EduSubject eduSubjectFromDb = getByTitle(eduSubject.getTitle());
        if (eduSubjectFromDb == null) {
            return super.save(eduSubject);
        }
        return false;
    }

    /**
     * @Description 根据ID查找分类
     * @Date 2020/3/3 0003 19:48
     * @param id
     * @return com.zeny.edu.eduservice.entity.EduSubject
     **/
    @Override
    public EduSubject getSubjectById(String id) {
        return baseMapper.selectById(id);
    }

    private EduSubject getByTitle(String title) {
        QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
        wrapper.eq("title", title);
        return baseMapper.selectOne(wrapper);
    }

    private boolean isExistChild(String parentId) {
        QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", parentId);
        List<EduSubject> eduSubjectList = baseMapper.selectList(wrapper);
        return eduSubjectList.size() > 0;
    }

    /**
     * @Description 构建索引
     * @Date 2020/3/2 0002 15:44
     * @param subjectNestedVoList
     * @return java.util.Map<java.lang.String,java.lang.Object>
     **/
    private Map<String, Object> getSubMap(List<SubjectNestedVo> subjectNestedVoList) {
        Map<String, Object> map = new HashMap<>();
        for (SubjectNestedVo subjectNestedVo : subjectNestedVoList) {
            map.put(subjectNestedVo.getId(), subjectNestedVo);
        }
        return map;
    }

    /**
     * @Description 封装SubjectNestedVo
     * @Date 2020/3/2 0002 15:44
     * @param
     * @return java.util.List<com.zeny.edu.eduservice.entity.dto.SubjectNestedVo>
     **/
    private List<SubjectNestedVo> getSubjectNestedVoListByDb() {
        List<EduSubject> eduSubjectList = baseMapper.selectList(null);
        List<SubjectNestedVo> subjectNestedVoList = new ArrayList<>();
        for (EduSubject eduSubject : eduSubjectList) {
            SubjectNestedVo subjectNestedVo = new SubjectNestedVo();
            BeanUtils.copyProperties(eduSubject, subjectNestedVo);
            subjectNestedVoList.add(subjectNestedVo);
        }
        return subjectNestedVoList;
    }

    private EduSubject isExistOne(String value, String parentId) {
        QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
        wrapper.eq("title", value);
        wrapper.eq("parent_id", parentId);
        return baseMapper.selectOne(wrapper);
    }
}